<!-- 自定义金额输入键盘 -->
<template>
	<view class="vk-data-input-keyboard-money">
		<!-- 页面开始 -->
		<u-input
			v-if="showInput"
			:value="inputVal"
			:modelValue="inputVal"
			:placeholder="placeholder"
			:custom-style="customStyle"
			type="select"
			@click="isShow = true"
		></u-input>
		<u-keyboard
			:value="isShow"
			:modelValue="isShow"
			mode="number"
			:dot-enabled="dotEnabled"
			:tooltip="tooltip"
			:tips="tips"
			:show-tips="showTips"
			:cancel-btn="cancelBtn"
			:confirm-btn="confirmBtn"
			:mask="mask"
			:z-index="zIndex"
			:random="random"
			:safe-area-inset-bottom="safeAreaInsetBottom"
			:mask-close-able="maskCloseAble"
			:confirm-text="confirmText"
			:cancel-text="cancelText"
			@input="onPopupShow"
			@change="onChange"
			@backspace="onBackspace"
			@confirm="onConfirm"
			@cancel="onCancel"
		></u-keyboard>
		<!-- 页面结束 -->
	</view>
</template>
<script>
	export default {
		name: "vk-data-input-keyboard-money",
		emits: ["update:modelValue", "input", "update:show", "confirm", "cancel", "open", "close"],
		props: {
			// 表单值
			value: {},
			modelValue: {},
			// 是否显示input
			showInput: {
				type: Boolean,
				default: true
			},
			show: {
				type: Boolean,
				default: false
			},
			// 提示
			placeholder: {
				type: String
			},
			customStyle: {
				type: Object
			},
			// 小数点位数
			precision: {
				type: Number,
				default: 2
			},
			max: {
				type: Number,
				default: 1000000000000,
			},
			min: {
				type: Number
			},
			// 是否显示键盘的"."符号
			dotEnabled: {
				type: Boolean,
				default: true
			},
			// 是否显示顶部工具条
			tooltip: {
				type: Boolean,
				default: true
			},
			// 是否显示工具条中间的提示
			showTips: {
				type: Boolean,
				default: true
			},
			// 工具条中间的提示文字
			tips: {
				type: String,
				default: "金额键盘"
			},
			// 是否显示工具条左边的"取消"按钮
			cancelBtn: {
				type: Boolean,
				default: true
			},
			// 是否显示工具条右边的"完成"按钮
			confirmBtn: {
				type: Boolean,
				default: true
			},
			// 是否打乱键盘按键的顺序
			random: {
				type: Boolean,
				default: false
			},
			// 是否开启底部安全区适配，开启的话，会在iPhoneX机型底部添加一定的内边距
			safeAreaInsetBottom: {
				type: Boolean,
				default: true
			},
			// 是否允许通过点击遮罩关闭键盘
			maskCloseAble: {
				type: Boolean,
				default: true
			},
			// 是否显示遮罩，某些时候数字键盘时，用户希望看到自己的数值，所以可能不想要遮罩
			mask: {
				type: Boolean,
				default: true
			},
			// z-index值
			zIndex: {
				type: [Number, String],
				default: ""
			},
			// 取消按钮的文字
			cancelText: {
				type: String,
				default: "取消"
			},
			// 确认按钮的文字
			confirmText: {
				type: String,
				default: "确认"
			}
		},
		data: function() {
			// 组件创建时，进行数据初始化
			return {
				isShow: false,
				inputVal: ""
			};
		},
		mounted() {
			this.init();
		},
		methods: {
			// 初始化
			init() {
				let vk = uni.vk;
				let { valueCom: value } = this;
				if (!isNaN(value) && vk.pubfn.isNotNull(value)) {
					value = Number(value);
					this._updateValue(value);
				}
			},
			// 向父组件发送更新value事件
			_updateValue(value) {
				this.$emit("input", value);
				this.$emit("update:modelValue", value);
			},
			onPopupShow(value) {
				this.isShow = value;
			},
			// 监听 - 打开
			onOpen() {
				this.$emit("open");
			},
			// 监听 - 关闭
			onClose() {
				let vk = uni.vk;
				let { inputVal, min } = this;
				if (vk.pubfn.isNotNull(min) && inputVal !== "") {
					if (inputVal < min) {
						inputVal = min + "";
						let value = this._inputValToValue(inputVal);
						this._updateValue(value);
					}
				}
				this.$emit("close");
			},
			// 按键被点击(点击退格键不会触发此事件)
			onChange(newVal) {
				// 将每次按键的值拼接到value变量中，注意+=写法
				let value = "";
				let { inputVal } = this;
				inputVal += newVal;
				this.$nextTick(() => {
					inputVal = this._valFilter(inputVal);
					this.inputVal = inputVal;
					let value = this._inputValToValue(inputVal);
					this._updateValue(value);
				});
				this.vibrateShort();
			},
			// 退格键被点击
			onBackspace(count) {
				let { inputVal } = this;
				if (inputVal && inputVal.length) {
					let num = 1;
					// 按的时间越长,删速度越快.
					if (count >= 8) {
						num = inputVal.length > 6 ? 6 : inputVal.length;
					} else if (count >= 5) {
						num = inputVal.length > 4 ? 4 : inputVal.length;
					} else if (count >= 3) {
						num = inputVal.length > 2 ? 2 : inputVal.length;
					}
					inputVal = inputVal.substr(0, inputVal.length - num);
					if (inputVal[inputVal.length - 1] === ".") {
						inputVal = inputVal.substr(0, inputVal.length - 1);
					}
				}
				this.inputVal = inputVal;
				let value = this._inputValToValue(inputVal);
				this._updateValue(value);
				this.vibrateShort();
			},
			onCancel() {
				this.$emit("cancel");
			},
			onConfirm() {
				this.$emit("confirm", this.valueCom);
			},
			vibrateShort() {
				// #ifdef MP-WEIXIN
				uni.vibrateShort();
				// #endif
			},
			// inputVal 转 value
			_inputValToValue(inputVal) {
				if (inputVal === "") return "";
				let value = Number(inputVal);
				// 此处必须做四舍五入取整,否则会出现精度不准确。
				return Math.round(value * 100);
			},
			// value 转 inputVal
			_valueToInputVal(value) {
				let vk = uni.vk;
				let { precision } = this;
				if (isNaN(value) || vk.pubfn.isNull(value)) return "";
				value = Number(value);
				return parseFloat((value / 100).toFixed(precision)).toString();
			},
			// inputVal数据过滤
			_valFilter(inputVal) {
				let vk = uni.vk;
				let { precision, mode, max } = this;
				if (precision != undefined) {
					// 小数位数限制
					let dianIndex = inputVal.indexOf(".");
					if (dianIndex > -1) {
						inputVal = inputVal.substring(0, dianIndex + precision + 1);
					}
				}
				// 最大值限制
				if (vk.pubfn.isNotNull(max)) {
					if (parseFloat(inputVal) > max) {
						inputVal = max + "";
					}
				}
				return inputVal;
			}
		},
		watch: {
			valueCom: {
				immediate: true,
				handler: function(newVal) {
					this.inputVal = this._valueToInputVal(newVal);
				}
			},
			show(newVal) {
				this.isShow = newVal;
			},
			isShow(newVal) {
				this.$emit("update:show", newVal);
				if (newVal) {
					// 打开
					this.onOpen();
				} else {
					// 关闭
					this.onClose();
				}
			}
		},
		// 计算属性
		computed: {
			valueCom() {
				// #ifdef VUE2
				return this.value;
				// #endif

				// #ifdef VUE3
				return this.modelValue;
				// #endif
			}
		}
	};
</script>

<style lang="scss" scoped>
	.vk-data-input-keyboard-money {
		position: relative;
		-webkit-box-flex: 1;
		padding: 0px;
		border-color: rgb(220, 223, 230);
		text-align: left;
		width: 100%;
	}
</style>